<script setup lang="ts">
import { FormProps } from "@/views/hooks";
import { onMounted, ref } from "vue";
import { getMenuList, getPermissionMenu, Menu } from "@/api/system";
import { handleTree } from "@/utils/tree";
import type Node from "element-plus/es/components/tree/src/model/node";

const props = withDefaults(defineProps<FormProps<any>>(), {
  formInline: () => ({
    permissionId: "",
    menu: []
  })
});
const newFormInline = ref(props.formInline);

const treeRef = ref();
const menus = ref<Array<Menu>>([]);
const loadFlag = ref<boolean>(true);
const loadFlag2 = ref<boolean>(true);
const checked = ref();

onMounted(() => {
  getPermissionMenu(newFormInline.value.permissionId).then(res => {
    newFormInline.value.menu = res;
    checked.value = res;
    loadFlag.value = false;
  });
  getMenuList({ current: 0, size: 10 }).then(res => {
    menus.value = handleTree(res);
    loadFlag2.value = false;
  });
});

const disable = (_: any, node: Node): boolean => {
  return !(0 === node?.childNodes.length ?? 0);
};

function onClick(_: Menu, status: any) {
  newFormInline.value.menu = [...status.halfCheckedKeys, ...status.checkedKeys];
}

/**处理父子节点非严格模式下关联问题*/
function checkChange(data: Menu, check: boolean) {
  // 父节点操作
  if (data.parentId !== null) {
    if (check) {
      // 如果选中，设置父节点为选中
      treeRef.value.setChecked(data.parentId, true);
    } else {
      // 如果取消选中，检查父节点是否该取消选中（可能仍有子节点为选中状态）
      const parentNode = treeRef.value.getNode(data.parentId);
      let parentHasCheckedChild = false;
      for (
        let i = 0, parentChildLen = parentNode?.childNodes.length ?? 0;
        i < parentChildLen;
        i++
      ) {
        if (parentNode.childNodes[i].checked === true) {
          parentHasCheckedChild = true;
          break;
        }
      }
      if (!parentHasCheckedChild)
        treeRef.value.setChecked(data.parentId, false);
    }
  }
  // 子节点操作，如果取消选中，取消子节点选中
  if (data.children != null && check === false) {
    for (let j = 0, len = data.children.length; j < len; j++) {
      const childNode = treeRef.value.getNode(data.children[j].id);
      if (childNode.checked === true) {
        treeRef.value.setChecked(childNode.data.id, false);
      }
    }
  }
}
</script>

<template>
  <div v-loading="loadFlag && loadFlag2">
    <el-tree
      ref="treeRef"
      :data="menus"
      node-key="id"
      show-checkbox
      :height="500"
      :props="{
        label: 'title',
        disabled: disable
      }"
      :default-checked-keys="checked"
      default-expand-all
      check-strictly
      @check="onClick"
      @check-change="checkChange"
    />
  </div>
</template>
